﻿// Hubs/ProcedureHub.cs
using Microsoft.AspNetCore.SignalR;
using seejee_Backendium.Core.Interfaces;
using seejee_Backendium.Core.Models;

namespace seejee_Backendium.WEB.Hubs
{
    public class ProcedureHub : Hub
    {
        private readonly IProcedureService _procedureService;
        private readonly IBILogenAccListService _logenAccListService;
        private readonly IDynamicConnectionService _dynamicConnectionService;
        private readonly ILogger<ProcedureHub> _logger;

        // 存储活跃的连接和组件订阅
        private static readonly Dictionary<string, string> _connectionSubscriptions = new();

        public ProcedureHub(
            IProcedureService procedureService,
            IBILogenAccListService logenAccListService,
            IDynamicConnectionService dynamicConnectionService,
            ILogger<ProcedureHub> logger)
        {
            _procedureService = procedureService;
            _logenAccListService = logenAccListService;
            _dynamicConnectionService = dynamicConnectionService;
            _logger = logger;
        }

        // 客户端订阅组件实时更新
        public async Task SubscribeToComponent(string componentId, int DBContent, string procedureName)
        {
            // 记录订阅关系
            _connectionSubscriptions[Context.ConnectionId] = componentId;

            // 开始定期执行并推送
            _ = StartProcedureStream(Context.ConnectionId, componentId, DBContent, procedureName);

            await Clients.Caller.SendAsync("Subscribed", $"已订阅组件 {componentId} 的实时更新");
        }

        // 取消订阅
        public async Task UnsubscribeFromComponent(string componentId)
        {
            _connectionSubscriptions.Remove(Context.ConnectionId);
            await Clients.Caller.SendAsync("Unsubscribed", $"已取消订阅组件 {componentId}");
        }

        // 实时执行存储过程并推送结果
        private async Task StartProcedureStream(string connectionId, string componentId, int DBContent, string procedureName)
        {
            try
            {
                // 获取数据库连接信息
                var dbInfo = await _logenAccListService.GetDBContentAsync(DBContent);
                if (dbInfo == null) return;

                string connectionString = _dynamicConnectionService.BuildConnectionString(dbInfo);

                // 定期执行并推送
                var timer = new System.Timers.Timer(5000); // 5秒间隔
                timer.Elapsed += async (sender, e) =>
                {
                    try
                    {
                        if (_connectionSubscriptions.ContainsKey(connectionId))
                        {
                            var procedureDto = new ProcedureDto
                            {
                                sp_name = procedureName,
                                sp_text = await GetProcedureText(procedureName)
                            };

                            var result = await _procedureService.ExecuteProcedureWithConnectionAsync(procedureDto, connectionString);

                            await Clients.Client(connectionId).SendAsync("DataUpdate", new
                            {
                                componentId,
                                data = result,
                                timestamp = DateTime.Now
                            });
                        }
                        else
                        {
                            // 如果连接已取消订阅，停止定时器
                            timer.Stop();
                            timer.Dispose();
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "实时执行存储过程失败");
                        await Clients.Client(connectionId).SendAsync("Error", new
                        {
                            componentId,
                            error = ex.Message
                        });
                    }
                };

                timer.Start();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "启动实时流失败");
                await Clients.Client(connectionId).SendAsync("Error", new
                {
                    componentId,
                    error = ex.Message
                });
            }
        }

        private async Task<string> GetProcedureText(string procedureName)
        {
            // 实现获取存储过程文本的逻辑
            return "存储过程脚本内容";
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {
            // 连接断开时清理订阅
            _connectionSubscriptions.Remove(Context.ConnectionId);
            await base.OnDisconnectedAsync(exception);
        }
    }
}